//
//  NSURL+SFRoute.m
//  SFModuleManager
//
//  Created by zhouxr on 2021/5/12.
//

#import "NSURL+SFRoute.h"

NSString * const kSFModuleRoutePlaceHolderScheme = @"kSFModuleRoutePlaceHolderScheme";

@implementation NSURL (SFRoute)

+ (NSURL *)sf_URLWithRoute:(NSString *)route {
    if (![route isKindOfClass:[NSString class]] || route.length == 0) {
        return nil;
    }

    NSRange queryRange = [route rangeOfString:@"?"];
    if (queryRange.location != NSNotFound && queryRange.length > 0) {
        // 对参数进行 url encode
        NSMutableString *str = [NSMutableString stringWithString:[route substringToIndex:queryRange.location]];
        NSDictionary<NSString *, NSString *> *query = [self sf_dictionaryFromRouteQuery:[route substringFromIndex:queryRange.location + 1]];
        NSArray<NSString *> *keyArr = [query allKeys];
        for (NSInteger idx = 0; idx < keyArr.count; idx ++) {
            [str appendString:(idx == 0 ? @"?" : @"&")];
            NSString *key = keyArr[idx];
            NSString *value = [[query valueForKey:key] sf_routeUrlEncode];
            [str appendFormat:@"%@=%@", key, value];
        }
        route = str;
    }
    
    // 拼接成假的url,再解析
    NSRange schemeRange = [route rangeOfString:@"://"];
    if (schemeRange.length == 0 || (queryRange.length > 0 && schemeRange.location > queryRange.location)) {
        route = [kSFModuleRoutePlaceHolderScheme stringByAppendingFormat:@"://%@", route];
    } else if (schemeRange.location == 0) {
        route = [kSFModuleRoutePlaceHolderScheme stringByAppendingString:route];
    }
    
    return [NSURL URLWithString:route];
}

#pragma mark - Private

+ (NSDictionary *)sf_dictionaryFromRouteQuery:(NSString *)query {
    if (![query isKindOfClass:[NSString class]] || query.length == 0) {
        return nil;
    }
    NSCharacterSet *delimiterSet = [NSCharacterSet characterSetWithCharactersInString:@"&;"];
    NSMutableDictionary *pairs = [NSMutableDictionary dictionary];
    NSScanner *scanner = [[NSScanner alloc] initWithString:query];
    while (![scanner isAtEnd]) {
        NSString *pairString = nil;
        [scanner scanUpToCharactersFromSet:delimiterSet intoString:&pairString];
        [scanner scanCharactersFromSet:delimiterSet intoString:NULL];
        NSArray *kvPair = [pairString componentsSeparatedByString:@"="];
        if (kvPair.count == 2) {
            NSString *key = [[kvPair objectAtIndex:0]
                             stringByReplacingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
            NSString *value = [[kvPair objectAtIndex:1] stringByReplacingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
            [pairs setObject:value forKey:key];
        }
    }
    
    return [pairs copy];
}
@end
